<template>
  <div class="part">
    <!-- 右上角按钮组 -->
    <div class="header-actions">
      <el-button type="success" size="medium" @click="exportScores" icon="el-icon-download">
        导出成绩
      </el-button>
    </div>

    <!-- 图表容器 -->
    <div v-if="!isNull" class="box" ref="box"></div>

    <!-- 无数据提示 -->
    <div v-else class="no-data">
      <span>该门考试还没人参加哦，请提醒学生参加考试。</span>
    </div>
  </div>
</template>

<script>
const XLSX = require('xlsx');
const { saveAs } = require('file-saver');

export default {
  name: 'ScorePart',
  data() {
    return {
      isNull: false,
      name: '', // 考试科目
      category: {
        '90分及以上': 0,
        '80-89分': 0,
        '70-79分': 0,
        '60-69分': 0,
        '60分以下': 0,
      },
      chart: null,
      scoresData: [] // 原始成绩数据，studentId 是警号
    };
  },
  created() {
    this.getScoreInfo();
  },
  methods: {
    getScoreInfo() {
      const examCode = this.$route.query.examCode;
      this.name = this.$route.query.subject;

      if (!examCode) {
        this.$message.error('缺少考试编码，无法加载成绩数据');
        this.isNull = true;
        return;
      }

      this.$axios(`/api/scores/${examCode}`)
        .then((res) => {
          const data = res.data.data;
          if (!data || data.length === 0) {
            this.isNull = true;
            this.$message.warning('该考试暂无成绩数据');
            return;
          }

          this.scoresData = data;

          // 补充学生信息
          this.fetchStudentDetails(data).then((enrichedData) => {
            this.initChart(enrichedData);
          });
        })
        .catch((error) => {
          this.$message.error('获取成绩数据失败，请稍后重试');
          this.isNull = true;
        });
    },

    // 批量获取学生姓名和身份证号（不使用 ?. 可选链）
    fetchStudentDetails(scoreList) {
      const promises = scoreList.map((item) => {
        const studentId = item.studentId; // 警号

        return this.$axios.get(`/api/student/${studentId}`)
          .then((res) => {
            const data = res.data;
            const student = data && data.data ? data.data : null;

            let studentName = '未知姓名';
            let cardId = '';
            let institute = '';

            if (student) {
              // 兼容多种字段名
              if (student.studentName) {
                studentName = student.studentName;
              }

              if (student.cardId) {
                cardId = student.cardId;
              }
              if (student.institute) {
                institute = student.institute;
              }
            }

            return {
              ...item,
              studentName: studentName,
              cardId: cardId,
              institute:institute
            };
          })
          .catch((err) => {
            return {
              ...item,
              studentName: '获取失败',
              cardId: ''
            };
          });
      });

      return Promise.all(promises);
    },

    initChart(data) {
      const box = this.$refs.box;
      if (!box) return;

      if (this.chart) {
        this.chart.dispose();
      }

      this.chart = this.$echarts.init(box);

      // 重置分类统计
      this.category = {
        '90分及以上': 0,
        '80-89分': 0,
        '70-79分': 0,
        '60-69分': 0,
        '60分以下': 0,
      };

      data.forEach((item) => {
        const score = item.etScore || 0;
        if (score >= 90) {
          this.category['90分及以上']++;
        } else if (score >= 80) {
          this.category['80-89分']++;
        } else if (score >= 70) {
          this.category['70-79分']++;
        } else if (score >= 60) {
          this.category['60-69分']++;
        } else {
          this.category['60分以下']++;
        }
      });

      const option = {
        title: {
          text: `${this.name} 分数段统计`,
          subtext: '成绩分布饼图',
          x: 'center'
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a}：<br/>{b}：{c}人 ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          data: ['90分及以上', '80-89分', '70-79分', '60-69分', '60分以下']
        },
        series: [
          {
            name: '分数段',
            type: 'pie',
            radius: '45%',
            center: ['50%', '50%'],
            data: Object.keys(this.category).map((key) => ({
              value: this.category[key],
              name: key
            })),
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      };

      this.chart.setOption(option);
    },

    exportScores() {
      if (!this.scoresData || this.scoresData.length === 0) {
        this.$message.warning('没有可导出的成绩数据');
        return;
      }

      this.$message.info('正在导出，请稍候...');

      this.fetchStudentDetails(this.scoresData)
        .then((enrichedData) => {
          const wsData = [
            ['警号', '身份证号', '姓名','单位所在地', '分数'],
            ...enrichedData.map((item) => [
              item.studentId,           // 警号
              item.cardId || '',        // 身份证号
              item.studentName || '',   // 姓名
              item.institute||'',       //单位所在地
              item.etScore || '0'        // 分数
            ])
          ];

          const ws = XLSX.utils.aoa_to_sheet(wsData);
          const wb = XLSX.utils.book_new();
          XLSX.utils.book_append_sheet(wb, ws, '成绩表');

          const dateStr = new Date().toISOString().slice(0, 10);
          const fileName = `${this.name}_成绩_${dateStr}.xlsx`;

          const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
          const blob = new Blob([wbout], { type: 'application/octet-stream' });
          saveAs(blob, fileName);

          this.$message.success(`《${this.name}》成绩导出成功！`);
        })
        .catch((err) => {
          this.$message.error('导出失败，请稍后重试');
        });
    }
  }
};
</script>

<style lang="less" scoped>
.part {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 0;

  .header-actions {
    text-align: right;
    width: 100%;
    margin-bottom: 20px;
  }

  .box {
    width: 800px;
    height: 600px;
    margin-left: 40px;
    border: 1px solid #ddd;
    border-radius: 8px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  }

  .no-data {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 300px;
    color: #999;
    font-size: 16px;
  }
}
</style>